/*
 * FactoryBasic.java
 *
 * Created on 21 de febrero de 2007, 11:25 AM
 *
 * To change this template, choose Tools | Template Manager
 * and open the template in the editor.
 */

package basic;

import ig.util.ServiceLocator;

import java.io.BufferedReader;
import java.io.File;
import java.io.FileInputStream;
import java.io.FileReader;
import java.sql.*;
import java.util.Hashtable;
import java.util.Map;
import java.util.Properties;
import javax.naming.NamingException;
import javax.sql.DataSource;


import org.w3c.dom.Element;

/**
 * @author jsanchez
 */
public abstract class FactoryBasic {
    
    /** Creates a new instance of FactoryBasic
     * @throws NamingException
     * @throws Exception
     * @throws IOException */
    @SuppressWarnings("unchecked")
    public FactoryBasic(boolean test) throws Exception{
        if(!test){
            Object DS_=getAtributo("DS");
            if(DS_!=null && !DS_.equals("")){
                String SQL;
                conn1=getDataSource(DS_.toString().trim());
                prep1=conn1.prepareStatement(SQL=getAtributo("QUERY").toString());
                getAtributo("PARAMETROS");
                //System.out.println("SQL:"+SQL);
            }
        }
    }
    
    public void executeQuery(Map<Object,Object> _parametros) throws InstantiationException, IllegalAccessException, ClassNotFoundException, SQLException{
        this.setParametrosPreparedStatement(prep1, _parametros,parametros);
        resul1=prep1.executeQuery();
    }
    private ServiceLocator serviceLocator = null;
    
    /**
     * @return the serviceLocator
     * @uml.property name="serviceLocator"
     */
    private ServiceLocator getServiceLocator() {
        if (serviceLocator == null) {
            serviceLocator = new ServiceLocator();
        }
        return serviceLocator;
    }
    
    public Connection getDataSource(String DS) throws Exception {
        try {
            return getServiceLocator().getDataSource("java:/" + DS.trim()).getConnection();
        } catch (Exception e) {
        }

        FileInputStream fis = null;
        try {
            Properties properties = new Properties();
            properties.load(fis = new FileInputStream(new File("server/"+DS+"-DS.properties")));
            Class.forName(properties.getProperty("driver"));
            return DriverManager.getConnection(properties.getProperty("url"), properties);    
        } catch (SQLException e) {
            System.out.println(" DataSource no encontrado : "+DS+" :"+e.toString());
            throw e;
        } catch (Exception e) {
            System.out.println(" DataSource no encontrado : "+DS+" :"+e.toString());
            throw new SQLException(e);
        }finally{
            try { fis.close(); } catch (Exception e) {}
        }        
    }
    
    public abstract Object[] getData(Map<Object,Object> parametros) throws Exception;
    
    public void close(Connection connection) {
        try {
            connection.close();
        } catch (Exception e) {
        }
    }
    
    public void close(PreparedStatement preparedStatement) {
        try {
            preparedStatement.close();
        } catch (Exception e) {
        }
    }
    
    public void close(ResultSet resultSet) {
        try {
            resultSet.close();
        } catch (Exception e) {
        }
    }
    
    public void closeAll() {
        try {
            conn1.close();
        } catch (Exception e) {
        }
        try {
            conn2.close();
        } catch (Exception e) {
        }
        try {
            prep1.close();
        } catch (Exception e) {
        }
        try {
            prep2.close();
        } catch (Exception e) {
        }
        try {
            prep3.close();
        } catch (Exception e) {
        }
        try {
            prep4.close();
        } catch (Exception e) {
        }
        try {
            prep5.close();
        } catch (Exception e) {
        }
        try {
            resul1.close();
        } catch (Exception e) {
        }
        try {
            resul2.close();
        } catch (Exception e) {
        }
        try {
            resul3.close();
        } catch (Exception e) {
        }
        try {
            resul4.close();
        } catch (Exception e) {
        }
        try {
            resul5.close();
        } catch (Exception e) {
        }
    }
    
    /**
     * 	<atributos>
     *		<query>
     *			select * from where
     *		</query>
     *		<parametros nombre='FECHA_CORTE'/>
     *		<parametros nombre='FECHA_CORTE'/>
     *	</atributos>
     *
     *@param es el nombre del parametros que se quiere buscar
     * @throws Exception
     */
    public Object getAtributo(String nombre) throws Exception,IllegalAccessException, ClassNotFoundException {
        
        File xml = new File("xml-bean/"+this.getClass().getSimpleName()+".xml");
        //File xml = new File(getClass().getResource("/xml-bean/"+this.getClass().getSimpleName()+".xml").getPath());
        System.out.println("get "+nombre+" in "+this.getClass().getSimpleName()+".xml");
        FileReader fr = new FileReader(xml );
        BufferedReader entrada=new BufferedReader(fr);
        try {
            String linea = null;
            StringBuilder XML = new StringBuilder();
            while((linea = entrada.readLine()) != null){
                XML.append(linea.toUpperCase()+"\n");
            }

            parametros = new Hashtable<Integer, Object>();
            org.w3c.dom.Document doc = parse(XML.toString());

            if (nombre.toUpperCase().equals("QUERY")){
                return doc.getChildNodes().item(0).getTextContent();
            }else{
                String VALOR = "";
                Integer item = 3;
                Integer i=1;
                while (VALOR != null) {
                    try {
                        VALOR =(((Element)doc.getChildNodes().item(0)).getChildNodes().item(item)).getAttributes().getNamedItem("NOMBRE").getNodeValue();
                    } catch (Exception e) {
                        try {
                            VALOR =(((Element)doc.getChildNodes().item(0)).getChildNodes().item(item)).getAttributes().getNamedItem("DS").getNodeValue();
                            if(nombre.toUpperCase().equals("DS") ){
                                this.DS=VALOR;
                                return this.DS;
                            }
                            VALOR ="";
                        } catch (Exception ex) {
                            try {
                                VALOR =(((Element)doc.getChildNodes().item(0)).getChildNodes().item(item)).getAttributes().getNamedItem("PC").getNodeValue();
                                if(nombre.toUpperCase().equals("PC") ){
                                    return VALOR;
                                }
                                VALOR="";
                            } catch (Exception exx) {
                                try {
                                    VALOR =(((Element)doc.getChildNodes().item(0)).getChildNodes().item(item)).getAttributes().getNamedItem("TIPOENTIDAD").getNodeValue();
                                    if(nombre.toUpperCase().equals("TIPOENTIDAD") ){
                                        return VALOR;
                                    }
                                    VALOR="";
                                } catch (Exception exxx) {
                                    try {
                                        VALOR =(((Element)doc.getChildNodes().item(0)).getChildNodes().item(item)).getAttributes().getNamedItem("CODIGO").getNodeValue();
                                        if(nombre.toUpperCase().equals("CODIGO") ){
                                            return VALOR;
                                        }
                                        VALOR="";
                                    } catch (Exception exxxx) {
                                        try {
                                            VALOR =(((Element)doc.getChildNodes().item(0)).getChildNodes().item(item)).getAttributes().getNamedItem("AREAINFORMACION").getNodeValue();
                                            if(nombre.toUpperCase().equals("AREAINFORMACION") ){
                                                return VALOR;
                                            }
                                            VALOR="";
                                        } catch (Exception exxxxx) {
                                            try {
                                                VALOR =(((Element)doc.getChildNodes().item(0)).getChildNodes().item(item)).getAttributes().getNamedItem("TIPOINFORME").getNodeValue();
                                                if(nombre.toUpperCase().equals("TIPOINFORME") ){
                                                    return VALOR;
                                                }
                                                VALOR="";
                                            } catch (Exception exxxxxx) {
                                                VALOR = null;
                                            }
                                        }
                                    }
                                }
                            }
                        }
                    }
                    item+=2;
                    if (VALOR!=null && !VALOR.equals(""))
                        parametros.put(i++, VALOR);
                }
                if(nombre.toUpperCase().equals("PARAMETROS") || nombre.toUpperCase().equals("PARAM"))
                    return parametros;
                else
                    return null;
            }
        } catch (Exception e) {
            e.printStackTrace();
            throw e;
        }finally{
            try {fr.close();} catch (Exception e) {}
            try {entrada.close();} catch (Exception e) {}
        }
    }
    
    private void setParametrosPreparedStatement(PreparedStatement prep,Map<Object, Object> parametros,Hashtable<Integer,Object> paramXML)
    throws InstantiationException, IllegalAccessException,
            ClassNotFoundException, SQLException {
        for (int i = 1; i <= paramXML.size(); i++) {
            Object obj=parametros.get(paramXML.get(i));
            if (obj instanceof java.lang.String)
                prep.setString(i,obj.toString());
            else if (obj instanceof java.lang.Integer)
                prep.setInt(i,Integer.valueOf(obj.toString()));
            else if (obj instanceof java.lang.Double)
                prep.setDouble(i,Double.valueOf(obj.toString()));
            else if (obj instanceof java.lang.Long)
                prep.setLong(i,Long.valueOf(obj.toString()));
            else if (obj instanceof java.sql.Timestamp)
                prep.setTimestamp(i,(Timestamp) obj);
            else if (obj instanceof java.sql.Date)
                prep.setDate(i,(java.sql.Date) obj);
            else if (obj instanceof java.util.Date)
                prep.setDate(i,new java.sql.Date(((java.util.Date)obj).getTime()));
        }
    }
    
    private org.w3c.dom.Document parse(String xml)
    throws javax.xml.parsers.ParserConfigurationException,
            org.xml.sax.SAXException, java.io.IOException {
        
        javax.xml.parsers.DocumentBuilderFactory dbf = javax.xml.parsers.DocumentBuilderFactory.newInstance();
        dbf.setValidating(false);
        javax.xml.parsers.DocumentBuilder docbuilder;
        docbuilder = dbf.newDocumentBuilder();
        docbuilder.setErrorHandler(null);
        javax.xml.parsers.DocumentBuilder doc = docbuilder;
        return doc.parse(new org.xml.sax.InputSource(new java.io.StringReader(xml)));
    }
    
    public String DS = null;
    public Connection conn1;
    public Connection conn2;
    public PreparedStatement prep1;
    public PreparedStatement prep2;
    public PreparedStatement prep3;
    public PreparedStatement prep4;
    public PreparedStatement prep5;
    public ResultSet resul1;
    public ResultSet resul2;
    public ResultSet resul3;
    public ResultSet resul4;
    public ResultSet resul5;
    public Hashtable<Integer, Object> parametros = new Hashtable<Integer, Object>();
}
